package com.vcar.LDiceClient.chat
{
	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TextEvent;
	import flash.filters.DropShadowFilter;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.text.TextLineMetrics;
	import flash.utils.Dictionary;

	import mx.controls.Alert;

	public class CTextArea extends Sprite
	{
		public var tf:TextField;
		private var imgLayer:Sprite;
		private var _spaceWidth:Number;
		private var _lineHeight:Number;
		private var _objectLineDict:Dictionary;
		private var lastLines:Array;

		public function CTextArea(width:Number=100, defaultTextFormat:TextFormat=null)
		{
			_objectLineDict=new Dictionary(true);
			lastLines=new Array();

			tf=new TextField();
			tf.mouseWheelEnabled=false;
			tf.width=width;
			tf.multiline=true;
			tf.wordWrap=true;
			tf.border=false;
			tf.addEventListener(TextEvent.LINK, onLinkClick);
			if (defaultTextFormat == null)
			{
				defaultTextFormat=new TextFormat();
				defaultTextFormat.size=12;
				defaultTextFormat.font="Arial";
				defaultTextFormat.color=0x000000;
				defaultTextFormat.leading=3;
			}
			tf.defaultTextFormat=defaultTextFormat;
			tf.appendText(" \n");
			addChild(tf);
			imgLayer=new Sprite();
			addChild(imgLayer);

			var ttf:TextField=new TextField();
			ttf.autoSize=TextFieldAutoSize.LEFT;
			ttf.defaultTextFormat=tf.defaultTextFormat;
			ttf.text="          ";
			_spaceWidth=ttf.textWidth / 10;
			_lineHeight=ttf.textHeight;

			tf.height=tf.textHeight + _lineHeight;
			
			showDarkBorder(true);
		}

		public function appendComplexText(str:String):void
		{
			if (str == null || str == "")
				return;

			lastLines.push(str);
			if (lastLines.length > 10)
				lastLines.splice(0, 1);

			if (tf.height > 1500)
				clearText(); //如果超过1500像素，则清楚文本框，并保留最近10条记录。
			//^[([^\[\]=]+)=([^\[\]=]+)]$
			appendTextField(str);
		}

		private function appendTextField(str:String):void
		{
			str=str.replace("\r", "");
			var cur_tfm:TextFormat=tf.defaultTextFormat;
			var matchs:Array=str.match(/\[?[^\[\]]+\]?/g);
			var len:int=matchs.length;
			for (var i:int=0; i < len; i++)
			{
				var word:String=matchs[i];
				if (word.substr(0, 1) == "[" && word.substr(-1, 1) == "]" && word.indexOf("=") != -1)
				{
					var arg:String=word.split("=")[0].substring(1);
					var val:String=word.split("=")[1].substr(0, -1);
					switch (arg)
					{
						case "object":
						case "smile":
							try
							{
								var obj:DisplayObject=IExObject.factry.create(this, arg, val);
							}
							catch (e:Error)
							{
								break;
							}
							var sps:int=Math.ceil(obj.width / _spaceWidth);
							var lm:TextLineMetrics=tf.getLineMetrics(tf.numLines - 1);
							if (lm.width + obj.width > tf.width)
							{
								tf.appendText("\n");
								lm=tf.getLineMetrics(tf.numLines - 1);
							}
							tf.appendText(getSpace(sps));

							var preLineIndex:int=tf.numLines - 2 < 0 ? 0 : tf.numLines - 2;
							var preLineCharIndex:int=tf.getLineOffset(preLineIndex);
							var preLineTfm:TextFormat=tf.getTextFormat(preLineCharIndex);
							preLineTfm.leading=Math.max(Number(preLineTfm.leading), obj.height - _lineHeight);
							tf.setTextFormat(preLineTfm, preLineCharIndex);
							obj.x=lm.width + 2; // 2 leftmargin fix ???
							obj.y=tf.textHeight - obj.height + 5;

							if (_objectLineDict[tf.numLines - 1] == null)
								_objectLineDict[tf.numLines - 1]=[];
							var lineObject:Array=_objectLineDict[tf.numLines - 1];
							for (var j:int=lineObject.length - 1; j >= 0; j--)
							{
								lineObject[j].y=tf.textHeight - lineObject[j].height;
							}
							_objectLineDict[tf.numLines - 1].push(obj);
							obj.addEventListener(ChatExObjectEvent.CLICK, onChatExObjectClick);
							imgLayer.addChild(obj);
							break;
						case "color":
							cur_tfm.color=Number(val);
							break;
						case "link":
							var linkText:String=val.split("|")[0];
							cur_tfm.url="event:" + val;
							tf.appendText(linkText);
							tf.setTextFormat(cur_tfm, tf.length - linkText.length, tf.length);
							cur_tfm.url="";
							break;
						default:
							tf.appendText(word);
							tf.setTextFormat(cur_tfm, tf.length - word.length, tf.length);
							break;
					}
				}
				else
				{
					tf.appendText(word);
					tf.setTextFormat(cur_tfm, tf.length - word.length, tf.length);
				}
			}
			_change();
		}

		private function _change():void
		{
			tf.height=tf.textHeight + _lineHeight - 10;
			dispatchEvent(new Event(Event.CHANGE));
		}

		private function onChatExObjectClick(e:ChatExObjectEvent):void
		{
			var evt:ChatExObjectEvent=new ChatExObjectEvent(ChatExObjectEvent.CLICK);
			evt.data=e.data;
			evt.exObject=e.exObject;
			evt.targetType=e.targetType;
			dispatchEvent(evt);
		}

		private function onLinkClick(e:TextEvent):void
		{
			var evt:ChatExObjectEvent=new ChatExObjectEvent(ChatExObjectEvent.CLICK);
			evt.data=e.text;
			evt.exObject=null;
			evt.targetType="Link";
			dispatchEvent(evt);
		}

		public function showDarkBorder(b:Boolean):void
		{
			if (b)
			{
				//tf.filters=[new GlowFilter(0,1,3,3,255)];
				tf.filters=[new DropShadowFilter(0, 0, 0, 0.8, 2, 2, 10)];
			}
			else
			{
				tf.filters=[];
			}
		}

		private function getSpace(num:int):String
		{
			var tmps:String="";
			for (var i:int=0; i < num; i++)
				tmps+=" ";
			return tmps;
		}

		private function clearAllText():void
		{
			tf.text="";
			tf.appendText(" \n");
			tf.height=tf.textHeight + _lineHeight;
			_objectLineDict=new Dictionary(false);
			while (imgLayer.numChildren > 0)
				imgLayer.removeChildAt(0);
			_change();
		}

		private function clearText():void
		{
			clearAllText();
			for (var i:int=0; i < lastLines.length; i++)
			{
				appendTextField(lastLines[i]);
			}
		}

		public function appendText(str:String):void
		{
			tf.appendText(str);
			_change();
		}

		public function setWidth(width:Number):void
		{
			if (width == tf.width)
				return;

			tf.width=width;
			_objectLineDict=new Dictionary(false);
			while (imgLayer.numChildren > 0)
				imgLayer.removeChildAt(0);
		}
	}
}

